Repository navigation
feat: detect SSHole exposure, ban password logins to key-only accounts, and say what defends the box until the upgrade - #21
Merged
Conversation
…unts SSHole (CVE-2026-123158) is an OpenSSH authentication bypass on musl with PAM disabled, Alpine's default server included: a 257-1024 byte password makes the hash attempt fail, the failure reads as the same '*' the account stores, and the login succeeds. Fixed in OpenSSH 10.6p2. - vuln.sshole flags openssh-server builds older than 10.6p2 in the apk package database, on the host and in running containers: apk is the musl half of the vulnerable configuration. The PAM flavor and glibc distributions are not affected and are not reported. Alert only: a version names no attacker. - ssh.password-login alerts on password logins to key-only accounts (root, alpine by default; STACKDOG_SSHOLE_KEYONLY_USERS extends the list) and feeds the ban engine: Alpine's own incident guidance is to hunt exactly these lines. One offense per line, repeats numbered so the registry counts them. - STACKDOG_SSHOLE_ENABLED=false turns both off; the version check reads package databases through the same host-root mount as the PHP checks. Docs: README subsection, CHANGELOG, .env.sample, and an /am-i-affected style page at /sshole-check with an in-browser version check (ssh -V plus the platform conditions), wired into sitemap and footer. Tests: 468+8+108 pass, clippy -D warnings and fmt clean, website build 15/15.
One password login to a key-only account is already a foothold: waiting for the five-offense threshold hands the intruder time to switch the monitoring off. OffenseInput gains an immediate flag, and ssh.password-login sets it, so the first line bans the address. The gate still runs first: allowlisted and protected addresses are never touched. The exposure alerts now say what defends the box until the upgrade, so the Slack message is actionable on arrival: vuln.sshole names the first-line ban on password logins to key-only accounts, vuln.php2shell names the out-of-memory bans, the webshell scan and session.upload_ progress.enabled = 0. Tests: an end-to-end attack simulation on captured fixtures (Alpine 3.20's openssh 9.7_p1-r6 apk database and a real sshd login line from a lab container) walks exposure finding, log findings and the ban to an active block; a new test proves one line bans and the allowlist still holds. 469+8+108 pass, clippy -D warnings and fmt clean, website 15/15.
The two SSHole ban tests unwrapped apply_ip_ban, which panics on a Linux runner without root: the nftables backend fails with 'Operation not permitted' before the block is recorded. Mirror the existing pattern in test_apply_ip_ban_blocks_and_emits_alert_after_repeated_anomalies: on Linux without root, accept that error and skip the block assertions; the detection assertions still run everywhere. macOS keeps asserting the ban end to end.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
*the account stores (root, alpine), and the login succeeds. Fixed in OpenSSH 10.6p2. First exploits were seen within nine hours of disclosure.f76990b):vuln.sshole: flagsopenssh-serverolder than 10.6p2 in apk package databases (host + containers). apk is the musl half of the vulnerable configuration; the PAM flavor (openssh-server-pam) and glibc distros are not affected and not reported. Alert only.ssh.password-login: password logins to key-only accounts (root, alpine default,STACKDOG_SSHOLE_KEYONLY_USERSto extend) — the line Alpine's incident guidance says to hunt.STACKDOG_SSHOLE_ENABLED=falseturns both off (default: on).a2d07df): one of these logins is already a foothold; waiting for the five-offense threshold gives the intruder time to switch the monitoring off.OffenseInputgains animmediateflag andssh.password-loginsets it: the first line bans. The gate still runs first; allowlisted and protected addresses are never touched.a2d07df): exposure alerts now name the interim defense, so the notification is actionable on arrival —vuln.ssholenames the first-line ban,vuln.php2shellnames the out-of-memory bans, the webshell scan andsession.upload_progress.enabled = 0.9.7_p1-r6apk database and a real sshd login line from a lab container): exposure finding -> log findings -> active block. One-line-ban test with an allowlist control. Version parsing for10.6_p2-r0/OpenSSH_10.6p2/1:9.2p1-2+deb12u5, PAM/glibc exemption, detector positives and negatives. 469+8+108 pass, clippy -D warnings and fmt clean./sshole-check— "Am I affected by SSHole?" with an in-browser check (ssh -V + platform conditions), what to do now, how StackdogApp checks it, honest limits (including the immediate-ban allowlist warning). Website build 15/15.